feat(changelog): BitRouter-refined drafts + multi-channel announce - #29
feat(changelog): BitRouter-refined drafts + multi-channel announce#29SPIKESPIGEL404 wants to merge 1 commit into
Conversation
Extend the existing changelog sync into the refine → gate → publish loop for both BitRouter (OSS) and BitRouter Cloud. - sync-changelog.mjs: optional BitRouter refine pass (dogfood via api.bitrouter.ai) turns raw git-cliff bullets into benefit-oriented prose + a tighter title/description. Falls back to the deterministic draft when BITROUTER_API_KEY is absent, so nothing breaks without a key. Adds a `cloud` product path (inline body, cloud-<slug>.mdx) so the private repo is never fetched here. - source.config.ts: changelog frontmatter gains optional `product` (oss|cloud). - sync-changelog.yml: pass product/body/refine-key through from the dispatch. - announce-channels.mjs + announce-channels.yml (new): on a merged changelog entry, fan out to Discord / X (xurl) / Resend, tiered by version (alpha/patch → Discord only; x.y.0 → all). Per-channel copy is optionally spun by BitRouter, else derived deterministically. Every channel skips gracefully when unconfigured; entries are announced once (announced/<slug> tag) and a backfill age-guard prevents old-release spam. The review gate is unchanged: the changelog/sync PR. The docs page + RSS/Atom feed still publish via the site rebuild on merge. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Superseded by the changelog refactor on This branch rewrote Kept, moved up a layer. The tiering instinct here — prereleases and patches get less than Kept, then removed. The BitRouter refine pass was reimplemented against the new sync and unit-tested, then removed at the author's request before it ever ran — it only fired for non-routine entries, and every upstream release is a routine alpha. Recoverable from history if wanted. Dropped deliberately. The LLM-written per-channel copy. Notable and highlight entries now pass a curation gate, so their title and description are human-written; re-spinning that into an auto-posted public tweet is risk without upside. Announce copy is deterministic. Changed on safety grounds.
Bug this PR would have shipped. The announce workflow triggered only on Deferred. The Thanks — the tiering idea is the backbone of the whole refactor. |
What
Extends the existing changelog sync into the full refine → gate → publish loop for both BitRouter (OSS) and BitRouter Cloud, per the two-repo design (product repos just dispatch; all refinement/marketing lives here).
Changes
scripts/sync-changelog.mjscloudproduct path (inline body,cloud-<slug>.mdx).source.config.tsproduct: oss | cloud..github/workflows/sync-changelog.ymlproduct/ inlinebody/BITROUTER_API_KEYfrom the dispatch.scripts/announce-channels.mjs(new).github/workflows/announce-channels.yml(new)content/changelog/**; once-only viaannounced/<slug>tags.Tiering:
*-alpha/beta/rc*& patches → Discord only;x.y.0→ Discord + X + email.Safety
BITROUTER_API_KEY→ the existing deterministic draft; no channel secret → that channel is skipped (logged, non-fatal). Safe to merge before anything is wired.announced/<slug>tag); backfill merges older than 14d are skipped.changelog/syncPR) and docs/RSS publish are unchanged.Companion change (product repos)
Needs
bitrouter/bitrouter(andbitrouter-cloud) to fire the release dispatch so sync runs on release instead of the daily cron — a smallnotify-release.yml(already drafted on the bitrouter side). Cloud sendsproduct: cloud+ inlinebodysince this repo can't read the private repo.Secrets / vars to add here
Secrets:
BITROUTER_API_KEY(refine + channel copy),DISCORD_WEBHOOK_OSS,DISCORD_WEBHOOK_CLOUD,XURL_TOKENS,RESEND_API_KEYVariables:
SITE_URL,RESEND_AUDIENCE_OSS,RESEND_AUDIENCE_CLOUD,RESEND_FROMTested
node --check+ YAML parse on all files.v1.0.0-alpha.22→ valid.mdxwithproductfrontmatter.x.y.0cloud → all three; every channel skipped gracefully with no secrets; age-guard drops a 556d-old entry. All exit 0.Verify before enabling (couldn't test without live creds)
announce-channels.yml— pin to your version.RESEND_FROMdomain.🤖 Generated with Claude Code